/*
Abstract:
  Helper for working with headers and footers implementation

Last changed:
  $Id: header_footer_supp.cpp 82 2009-12-08 20:53:44Z vitamin.caig $

Author:
  (C) Vitamin/CAIG/2001

  This file is the part of Textator project
*/

#include "header_footer_supp.h"

#include "../io/streams.h"

#include <structures.h>
#include <symbol_check.h>

#include <text.h>

namespace
{
  class HeaderFooterControllerImpl : public Output::HeaderFooterController
  {
  public:
    HeaderFooterControllerImpl(const String& format, bool perLine) : Format(format), PerLine(perLine),
      Header(TEXT_GENERATED_FILE)
    {
    }

    virtual bool ParseEntry(const String& name, const String& value)
    {
      if (name == HEADER_NAME)
      {
        Header = value;
        return true;
      }
      else if (name == FOOTER_NAME)
      {
        Footer = value;
        return true;
      }
      else if (name == RAW_HEADER_NAME)
      {
        RawHeader = value;
        return true;
      }
      else if (name == RAW_FOOTER_NAME)
      {
        RawFooter = value;
        return true;
      }
      return false;
    }

    virtual void PutHeader(IO::TargetStream& stream) const
    {
      if (!Header.empty())
      {
        stream.PutString(Normalize(Header));
      }
      if (!RawHeader.empty())
      {
        stream.PutString(RawHeader);
      }
    }

    virtual void PutFooter(IO::TargetStream& stream) const
    {
      if (!Footer.empty())
      {
        stream.PutString(Normalize(Footer));
      }
      if (!RawFooter.empty())
      {
        stream.PutString(RawFooter);
      }
    }
  private:
    String Normalize(const String& str) const
    {
      if (PerLine)
      {
        String result;
        StringArray resArr;
        SplitString(str, std::ptr_fun(Symbol::IsLineEnd), resArr);
        for (StringArray::const_iterator it = resArr.begin(), lim = resArr.end(); it != lim; ++it)
        {
          result += StringFormatter::Process(Format, *it);
        }
        return result;
      }
      else
      {
        return StringFormatter::Process(Format, str);
      }
    }
  private:
    const String Format;
    const bool PerLine;
    String Header;
    String Footer;
    String RawHeader;
    String RawFooter;
  };
}

namespace Output
{
  HeaderFooterController::Ptr CreateBlockController(const String& format)
  {
    return HeaderFooterController::Ptr(new HeaderFooterControllerImpl(format, false));
  }
  HeaderFooterController::Ptr CreatePerLineController(const String& format)
  {
    return HeaderFooterController::Ptr(new HeaderFooterControllerImpl(format, true));
  }
}
